﻿
#include <thread>
#include <chrono>
#include "MayEvent/event.hpp"
#include "config.h"

using namespace std;

/**
 * @brief 事件回调函数，输出参数数量和参数值
 * 
 * @param arg_ 传入参数
 */
void helloFunc(PARGOBJ arg_)
{
    Argobj<int>& arg = getArgobj<int>(arg_);
    int count;
    arg.getArgument("count", &count);
    printf("hello, argCount=%zu, arg=%d\n", arg.getArgumentCount(), count);
}

/**
 * @brief 事件回调函数，打印信息
 * 
 * @param arg 传入参数
 */
void helloFunc2(PARGOBJ arg)
{
    printf("hello there!\n");
}

/**
 * @brief 事件回调函数，输出传入的信息
 * 
 * @param arg_ 传入参数
 */
void sayFunc(PARGOBJ arg_)
{
    Argobj<string>& arg = getArgobj<string>(arg_);
    string s;
    if (arg.getArgument("str", &s))
    {
        printf("fail\n");
    }
    printf("%s", s.c_str());
}

/**
 * @brief 事件呼叫线程，循环呼叫
 * 
 * @param e     事件调度对象
 * @param end   线程结束信号
 */
void otherThread(EventHandler* e, bool* end)
{
    for (int i = 0; i < 10; i++)
    {
        if (i % 2 == 0)
        {
            Argobj<int> arg;
            arg.addArgument("count", i);
            // 呼叫 Hello 事件
            e->callEvent("Hello", arg);
        }
        else
        {
            Argobj<string> arg;
            
            arg.addArgument("str", string("Call !! ") + to_string(i) + "\n");
            e->callEvent("Say", arg);
        }
        if (i == 5)
        {
            // 解绑事件
            e->unRegistEvent("Hello", &helloFunc2);
            printf(u8"helloFunc2 对于 Hello 事件解绑...\n");
        }
        this_thread::sleep_for(chrono::seconds(1));
    }
    *end = true;
}

/**
 * @brief 主函数
 */
int main()
{
#if (MAY_EVENT_WINDOWS)
    system("CHCP>nul2>nul 65001");
#endif
    EventHandler e;
    // 绑定事件
    e.addEvnet("Hello", &helloFunc);
    e.addEvnet("Hello", &helloFunc2);
    e.addEvnet("Say", &sayFunc);

    bool end = false;

    // 创建线程
    thread thr(&otherThread, &e, &end);
    thr.detach();

    // 等待线程结束
    while (!end)
    {
        this_thread::sleep_for(chrono::milliseconds(50));
    }

    e << "Hello" << "Say";

#ifdef MAY_EVENT_WINDOWS
    system("pause");
#endif

    return 0;
}
